package pers.cj.pdos.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import pers.cj.pdos.entity.*;
import pers.cj.pdos.mapper.*;
import pers.cj.pdos.service.IBorrowOutService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.cj.pdos.utils.PdosUtils;
import pers.cj.pdos.utils.Utils;
import pers.cj.pdos.utils.UuidUtils;
import pers.cj.pdos.vo.BorrowInGoodsVo;
import pers.cj.pdos.vo.BorrowInVo;
import pers.cj.pdos.vo.BorrowOutGoodsVo;
import pers.cj.pdos.vo.BorrowOutVo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 借出单生成后需要仓库管理关出库操作；后面如果是转销售后，状态改成已归还;如果是还的操作，则仓库管理员还需要进行入库操作 服务实现类
 * </p>
 *
 * @author chenj
 * @since 2019-11-04
 */
@Service
public class BorrowOutServiceImpl extends ServiceImpl<BorrowOutMapper, BorrowOut> implements IBorrowOutService {
    @Autowired
    BorrowOutMapper borrowOutMapper;
    @Autowired
    BorrowOutGoodsMapper borrowOutGoodsMapper;
    @Autowired
    GoodsSnMapper goodsSnMapper;
    @Autowired
    GoodsSnLogMapper goodsSnLogMapper;
    @Autowired
    GoodsStockMapper goodsStockMapper;
    @Autowired
    HouseWaitOutMapper houseWaitOutMapper;
    @Autowired
    HouseWaitOutGoodsMapper houseWaitOutGoodsMapper;

    @Override
    public List<BorrowOutVo> listVo(String companyId,
                                    Integer page,
                                    Integer limit,
                                    Boolean close,
                                    String search,
                                    String no,
                                    String goodsName,
                                    String remark,
                                    String custom,
                                    Date makeTime1,
                                    Date makeTime2,
                                    String storeId,
                                    String userStoreId,
                                    String userId,
                                    Date date1,
                                    Date date2,
                                    String houseId,
                                    String makeUserId,
                                    Integer outStatus) {
        return borrowOutMapper.listVo(companyId,
                Utils.genPage(page,limit),
                limit,
                null,
                close,
                search,
                no,
                goodsName,
                remark,
                custom,
                makeTime1,
                makeTime2,
                storeId,
                userStoreId,
                userId,
                date1,
                date2,
                houseId,
                makeUserId,
                outStatus);
    }

    @Override
    public long count(String companyId,
                      Boolean close,
                      String search,
                      String no,
                      String goodsName,
                      String remark,
                      String custom,
                      Date makeTime1,
                      Date makeTime2,
                      String storeId,
                      String userStoreId,
                      String userId,
                      Date date1,
                      Date date2,
                      String houseId,
                      String makeUserId,
                      Integer outStatus) {
        return borrowOutMapper.count(companyId,
                null,
                close,
                search,
                no,
                goodsName,
                remark,
                custom,
                makeTime1,
                makeTime2,
                storeId,
                userStoreId,
                userId,
                date1,
                date2,
                houseId,
                makeUserId,
                outStatus);
    }

    @Override
    public boolean checkNo(String no, String companyId) {
        return borrowOutMapper.selectCount(new QueryWrapper<BorrowOut>().eq("company_id",companyId).eq("no",no)) > 0;
    }

    @Override
    public boolean checkClose(BorrowOut borrowOut) {
        return borrowOutMapper.selectCount(new QueryWrapper<BorrowOut>().eq("id",borrowOut.getId()).eq("close",true))  > 0;
    }

    @Override
    public void insert(BusinessSet businessSet, BorrowOut borrowOut, List<BorrowOutGoods> borrowOutGoodsList, List<GoodsSn> goodsSnList, List<GoodsSnLog> goodsSnLogList) {
        borrowOutMapper.insert(borrowOut);
        borrowOutGoodsMapper.insertBatch(borrowOutGoodsList);

        BorrowOutVo borrowOutVo = borrowOutMapper.getVoById(borrowOut.getId());
        if (!PdosUtils.houseInOut(businessSet)) {
            //未启用出入库管理，直接添加库存
            processGoodsStock(1, borrowOutVo);
            if (!Utils.isEmpty(goodsSnList)) {
                goodsSnMapper.outByList(borrowOut.getHouseId(), goodsSnList);
                goodsSnLogMapper.insertBatch(goodsSnLogList);
            }
        } else {
            //启用库存管理，则添加待入库单数据
            processHouseWaitIn(1, borrowOutVo);
        }
    }

    @Override
    public void close(BorrowOut borrowOut, BusinessSet businessSet) {
        BorrowOutVo borrowOutVo = borrowOutMapper.getVoById(borrowOut.getId());

        //直接入库的进货单，则需要去除相应的库存和sn。
        if (borrowOutVo.getStatus() == 1) {
            processGoodsStock(2, borrowOutVo);
            //关闭进货单需要sn号需要处与出库状态
            List<GoodsSn> list = PdosUtils.genGoodsSnList(borrowOutVo.getBorrowOutGoodsVoList());
            if (!Utils.isEmpty(list)) {
                goodsSnMapper.inByList(borrowOutVo.getHouseId(), list);
            }
        } else {
            processHouseWaitIn(2,borrowOutVo);
        }

        BorrowOut temp = new BorrowOut();
        temp.setId(borrowOutVo.getId());
        temp.setClose(true);
        borrowOutMapper.updateById(temp);
    }

    @Override
    public BorrowOutVo getVoById(String id) {
        return borrowOutMapper.getVoById(id);
    }

    @Override
    public List<BorrowOutVo> listVoByIds(List<String> ids) {
        return borrowOutMapper.listVoByIds(ids);
    }


    /**
     * 待入库单处理
     * @param type 1.新增单据 2作废单据
     * @param borrowOutVo
     */
    private void processHouseWaitIn(int type, BorrowOutVo borrowOutVo) {
        if (type == 2) {
            HouseWaitOut houseWaitOut = new HouseWaitOut();
            houseWaitOut.setClose(true);
            houseWaitOutMapper.update(houseWaitOut, new QueryWrapper<HouseWaitOut>().eq("borrow_out_id", borrowOutVo.getId()));
            return ;
        }

        HouseWaitOut houseWaitOut = new HouseWaitOut();
        houseWaitOut.setId(UuidUtils.getUUID());
        houseWaitOut.setBorrowOutId(borrowOutVo.getId());
        houseWaitOut.setHouseId(borrowOutVo.getHouseId());
        houseWaitOut.setClose(false);
        houseWaitOut.setStatus(1);//待入库
        houseWaitOut.setType(4);//设置类型为借出
        houseWaitOut.setTime(new Date());
        houseWaitOut.setCompanyId(borrowOutVo.getCompanyId());
        houseWaitOutMapper.insert(houseWaitOut);

        List<HouseWaitOutGoods> houseWaitOutGoodsList = new ArrayList<>();
        for (BorrowOutGoodsVo vo : borrowOutVo.getBorrowOutGoodsVoList()) {
            HouseWaitOutGoods houseWaitOutGoods = new HouseWaitOutGoods();
            houseWaitOutGoods.setId(UuidUtils.getUUID());
            houseWaitOutGoods.setHouseWaitOutId(houseWaitOut.getId());
            houseWaitOutGoods.setBorrowOutGoodsId(vo.getId());
            houseWaitOutGoods.setGoodsId(vo.getGoodsId());
            houseWaitOutGoods.setHasOutNumber(new BigDecimal("0"));
            houseWaitOutGoods.setWaitOutNumber(vo.getNumber());
            houseWaitOutGoods.setNumber(vo.getNumber());
            houseWaitOutGoods.setUnitId(vo.getUnitId());
            houseWaitOutGoods.setTimes(vo.getTimes());
            houseWaitOutGoods.setCompanyId(borrowOutVo.getCompanyId());
            houseWaitOutGoodsList.add(houseWaitOutGoods);
        }
        houseWaitOutGoodsMapper.insertBatch(houseWaitOutGoodsList);
    }


    /**
     * 库存处理
     * @param type 1.新增单据 2作废单据
     * @param borrowOutVo
     */
    private void processGoodsStock(int type, BorrowOutVo borrowOutVo){
        List<GoodsStock> goodsStockList = new ArrayList<>();
        for (BorrowOutGoodsVo vo : borrowOutVo.getBorrowOutGoodsVoList()) {
            BigDecimal number = vo.getNumber().multiply(vo.getTimes());
            if (type == 1) {
                //新增借出单，需要减少库存
                number = number.negate();
            }
            //库存
            GoodsStock goodsStock = new GoodsStock();
            goodsStock.setId(UuidUtils.getUUID());
            goodsStock.setGoodsId(vo.getGoodsId());
            goodsStock.setHouseId(borrowOutVo.getHouseId());
            goodsStock.setNum(number); //数量*换算倍数
            goodsStock.setTime(new Date());
            goodsStock.setCompanyId(borrowOutVo.getCompanyId());
            goodsStockList.add(goodsStock);
        }

        goodsStockMapper.insertBatch(goodsStockList);
    }
}
